package dxn.nl.export.deal.service.impl;

import com.alibaba.fastjson2.JSON;
import dxn.boot.common.entity.CsColumnDto;
import dxn.nl.export.deal.export.ExportDealPageQueryBiz;
import dxn.nl.export.deal.export.ExportDealSteamQueryBiz;
import dxn.nl.export.deal.export.ExportSessionManager;
import dxn.nl.export.deal.netty.SocketManager;
import dxn.nl.export.deal.service.ExportFileService;
import dxn.nl.file.biz.ExportStatusEnum;
import dxn.nl.file.biz.po.FileExportApplyDetail;
import dxn.nl.file.biz.service.AppModelBaseService;
import dxn.nl.file.biz.service.ExportFileBaseService;
import dxn.nl.file.client.model.dto.CsExportDealTypeHeadDto;
import dxn.nl.file.client.model.dto.CsExportExcelHeadDto;
import dxn.nl.file.client.model.dto.CsExportExcelSheetHeadDto;
import dxn.nl.file.client.model.dto.TransferMessageDto;
import dxn.nl.file.client.model.enums.ExportDealResultTypeEnum;
import dxn.nl.file.client.model.enums.ExportFileTypeEnum;
import dxn.nl.file.client.model.enums.ExportMessageTypeEnum;
import dxn.nl.file.client.model.enums.ExportQueryDataTypeEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ExportFileServiceImpl implements ExportFileService {
    @Resource
    private ExportFileBaseService exportFileBaseService;

    @Resource
    private AppModelBaseService appModelBaseService;

    @Override
    public boolean dealExportFile(long exportId) {
        FileExportApplyDetail fileExportApplyDetail = exportFileBaseService.getBaseMapper().selectById(exportId);

        if (fileExportApplyDetail == null || 10 == fileExportApplyDetail.getStatus()) {
            return true;
        }

        if (fileExportApplyDetail.getStatus() == null) {
            fileExportApplyDetail.setStatus(0);
        }
        else if (10 == fileExportApplyDetail.getStatus()) {
            return true;
        }

        if (StringUtils.isBlank(fileExportApplyDetail.getAppId())
                || StringUtils.isBlank(fileExportApplyDetail.getModeCode())) {
            fileExportApplyDetail.setMessage("appId或者modeCode为空");
            exportFileBaseService.updateStatus(exportId, ExportStatusEnum.deal_exception,0, fileExportApplyDetail.getMessage());
            return true;
        }

        exportFileBaseService.updateStatus(fileExportApplyDetail.getId(), ExportStatusEnum.start_deal,0,null);

        try {
            TransferMessageDto csNioMessage = new TransferMessageDto(ExportMessageTypeEnum.query_head.code,
                    ExportFileTypeEnum.export.code, fileExportApplyDetail.getAppId(), fileExportApplyDetail.getModeCode(),
                    fileExportApplyDetail.getOrgCode(), fileExportApplyDetail.getOrgName(), fileExportApplyDetail.getApplyUserCode(),
                    fileExportApplyDetail.getApplyUserName());
            csNioMessage.getConfig().setServer(SocketManager.appSessionId);
            csNioMessage = SocketManager.sendData(csNioMessage,false);
            if(csNioMessage.getConfig().getDealResult() != ExportDealResultTypeEnum.continue_deal.code)
            {
                fileExportApplyDetail.setMessage("fail:"+csNioMessage.getConfig().getErrorMessage());
                exportFileBaseService.updateStatus(fileExportApplyDetail.getId(), ExportStatusEnum.deal_exception,0, fileExportApplyDetail.getMessage());
                return true;
            }

            CsExportDealTypeHeadDto dto = getExcelHead(fileExportApplyDetail,csNioMessage);
            if(dto.getSheetHeadMap().isEmpty())
            {
                fileExportApplyDetail.setMessage("获取表头信息失败:结果为空");
                exportFileBaseService.updateStatus(fileExportApplyDetail.getId(), ExportStatusEnum.deal_exception,0, fileExportApplyDetail.getMessage());
                return true;
            }

            if(dto.getExportType() == ExportQueryDataTypeEnum.page)
            {
                ExportDealPageQueryBiz pageQueryBiz = new ExportDealPageQueryBiz(dto.getSheetHeadMap()
                        ,exportFileBaseService, fileExportApplyDetail);
                pageQueryBiz.dealExport();
            }
            else
            {
                ExportDealSteamQueryBiz pageQueryBiz = new ExportDealSteamQueryBiz(dto.getSheetHeadMap()
                        ,exportFileBaseService, fileExportApplyDetail);

                // 流式查询，直接告诉客户端，可以继续了
                TransferMessageDto backPo = csNioMessage.convertNewResultMessage(ExportMessageTypeEnum.deal_result.code, ExportDealResultTypeEnum.continue_deal.code);
                String sendResult = SocketManager.sendDataNoWaitToServer(backPo);
                if(StringUtils.isNotBlank(sendResult))
                {
                    fileExportApplyDetail.setMessage(sendResult);
                    exportFileBaseService.updateStatus(fileExportApplyDetail.getId(), ExportStatusEnum.deal_exception,0, fileExportApplyDetail.getMessage());
                    return false;
                }

                ExportSessionManager.addExportUtil(csNioMessage.getConfig().getSessionId(),pageQueryBiz);
                pageQueryBiz.waitComplete();
            }
        }
        catch (Exception ex)
        {
            log.error("",ex);
            return false;
        }
        return true;
    }


    /**
     *
     * @param fileDetail
     * @param csNioMessage
     * @return
     */
    public CsExportDealTypeHeadDto getExcelHead(FileExportApplyDetail fileDetail, TransferMessageDto csNioMessage)
    {
        CsExportDealTypeHeadDto dto = null;
        if(csNioMessage.getData() != null || csNioMessage.getData().length > 0)
        {
            dto = JSON.parseObject(csNioMessage.getData(),CsExportDealTypeHeadDto.class);
        }
        if(dto == null)
        {
            dto = CsExportDealTypeHeadDto.pageDeal(null);
        }
        if(CollectionUtils.isEmpty(dto.getSheetHeadMap()))
        {
            List<CsColumnDto> columnDtos= appModelBaseService.selectExportTemplateByModeCode(csNioMessage.getConfig().getModeCode());
            if(!CollectionUtils.isEmpty(columnDtos))
            {
                List<CsExportExcelHeadDto> headDtos = new ArrayList<>();

                for(CsColumnDto dtoTemp:columnDtos)
                {
                    if(StringUtils.isBlank(dtoTemp.getDataIndex()) || StringUtils.isBlank(dtoTemp.getTitle()))
                    {
                        continue;
                    }

                    CsExportExcelHeadDto exportExcelHeadDto = new CsExportExcelHeadDto();
                    exportExcelHeadDto.setKey(dtoTemp.getDataIndex());
                    exportExcelHeadDto.setTitle(Arrays.stream(dtoTemp.getTitle().split(",")).toList());
                    exportExcelHeadDto.setOrder(dtoTemp.getOrder());
                    headDtos.add(exportExcelHeadDto);
                }
                dto.setDefaultSheetHeads(headDtos);
            }
        }

        // filter default sheet column
        CsExportExcelSheetHeadDto sheetHeadDto = dto.getDefaultSheetHeads();
        if(CollectionUtils.isEmpty(sheetHeadDto.getHeadDtoList()))
        {
            sheetHeadDto.setHasTitle(false);
        }
        else
        {
            if(!CollectionUtils.isEmpty(fileDetail.getExportColumn()))
            {
                List<CsExportExcelHeadDto> defaultSheetHead = sheetHeadDto.getHeadDtoList().stream()
                        .filter(c->fileDetail.getExportColumn().contains(c.getKey())).collect(Collectors.toList());
                dto.setDefaultSheetHeads(defaultSheetHead);
            }
        }

        // sort sheet column
        dto.sortHead();
        return dto;
    }

}
